package com.xydpeng.tech.order.service.order.statemachine;

import com.alibaba.cola.statemachine.Action;
import com.alibaba.cola.statemachine.Condition;
import com.alibaba.cola.statemachine.builder.StateMachineBuilder;
import com.alibaba.cola.statemachine.builder.StateMachineBuilderFactory;
import com.xydpeng.tech.order.enums.OrderStatusEnum;
import com.xydpeng.tech.order.service.order.statemachine.eventhandler.PendingToPaidOnPayEventHandler;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.SmartLifecycle;
import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author xydpeng
 * @version v1.0
 * @date: 2024/12/11
 * @description:
 */
@Slf4j
@Component
public class OrderStateMachineConfig implements SmartLifecycle {
    public static final String MACHINE_ID = "order_state_machine_1";
    private static final AtomicBoolean running = new AtomicBoolean(false);

    @Resource
    private PendingToPaidOnPayEventHandler pendingToPaidOnPayEventHandler;

    @Override
    public void start() {
        if (!running.get()) {
            initOrderStateMachine();
            running.set(true);
        }
    }

    @Override
    public void stop() {

    }

    @Override
    public boolean isRunning() {
        return running.get();
    }

    // PAY, SHIP, DELIVER, CANCEL
    private void initOrderStateMachine() {
        StateMachineBuilder<OrderStatusEnum, OrderEvent, OrderContext> builder = StateMachineBuilderFactory.create();

        builder.externalTransition()
                .from(OrderStatusEnum.PENDING)
                .to(OrderStatusEnum.PAID)
                .on(OrderEvent.PAY)
                .when(pendingToPaidOnPayEventHandler.checkCondition())
                .perform(pendingToPaidOnPayEventHandler.doAction());

        builder.externalTransition()
                .from(OrderStatusEnum.PAID)
                .to(OrderStatusEnum.SHIPPED)
                .on(OrderEvent.SHIP)
                .when(null)
                .perform(null);

        builder.externalTransition()
                .from(OrderStatusEnum.SHIPPED)
                .to(OrderStatusEnum.COMPLETED)
                .on(OrderEvent.DELIVER)
                .when(null)
                .perform(null);

        /*以下是取消事件触发的*/
        builder.externalTransition()
                .from(OrderStatusEnum.PENDING)
                .to(OrderStatusEnum.CANCELLED)
                .on(OrderEvent.CANCEL)
                .when(checkCondition())
                .perform(doAction());

        builder.externalTransition()
                .from(OrderStatusEnum.PAID)
                .to(OrderStatusEnum.CANCELLED)
                .on(OrderEvent.CANCEL)
                .when(null)
                .perform(null);

        builder.internalTransition().within(OrderStatusEnum.CANCELLED).on(OrderEvent.PAY).when(null).perform(null);

        builder.setFailCallback((sourceState, event, ctx) -> {
            log.warn("");
            ctx.setTransitFail();
        });
        builder.build(MACHINE_ID);
    }


    private Condition<OrderContext> checkCondition() {
        return (ctx) -> {
            System.out.println(Thread.currentThread().getName() + " do checkCondition");
            return true;
        };
    }

    private Action<OrderStatusEnum, OrderEvent, OrderContext> doAction() {
        return (from, to, event, ctx) -> {
            System.out.println(Thread.currentThread().getName() + "_" + ctx + " is operating from:" + from + " to:" + to + " on:" + event);
        };
    }


}
